<?php

namespace App\Services\Withdraw;

use App\Constant\Enum;
use App\Constant\User\UserMode;
use App\Exceptions\WithdrawException;
use App\Models\GroupApply;
use App\Models\ReturnMoneyLog;
use App\Models\Setting;
use App\Models\User;
use App\Models\UserWallet;
use App\Models\UserWalletActive;
use App\Models\UserWithdraw;
use App\Services\Commission\CommissionService;
use App\Services\Third\TransactionService;
use App\Services\Wallet\UserWalletService;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class GroupWithdrawService
{
    public static function apply(User $user, float $money = 0)
    {
        if (($user->mode & UserMode::DISABLE_WITHDRAW) === UserMode::DISABLE_WITHDRAW) {
            throw new WithdrawException("提现暂不可用，请联系客服");
        }
        if ($user->getAttribute('status') != Enum::STATUS_ENABLED) {
            throw new WithdrawException("用户状态异常，请联系客服");
        }

        $exchangeRate = Setting::get('exchange_rate') ?? '';
        if (empty($exchangeRate)) {
            throw new WithdrawException('兑换参数错误');
        }

        $wallet = $user->wallet;
        if (empty($wallet)) {
            throw new WithdrawException('用户帐号异常');
        }

        if ($wallet->on_withdraw) {
            throw new WithdrawException('已有提现处理中');
        }

        // 兑换需要扣除的金币数量
        if (empty($money)) {
//            $money = sprintf('%.2f', $wallet->commission_coins / $exchangeRate);
            //只提取整数部分（元）
            $money = floor($wallet->commission_coins / $exchangeRate);
        }
        $amount = intval($money * $exchangeRate);

        $totalCoins = $wallet->commission_coins - $wallet->locked_coins;
        $withdrawable = 1;
        if ($totalCoins < $withdrawable * $exchangeRate) {
            throw new WithdrawException(sprintf('满%s元才能提现', $withdrawable));
        }
        if (($totalCoins - $amount) < 0) {
            throw new WithdrawException('账户余额不足');
        }


        DB::beginTransaction();
        try {
            self::checkAccountBank($money);
            // 单位元
            $money = $amount / $exchangeRate;
            $walletType = Enum::WALLET_TYPE_COMMISSION;

            $withdraw = [
                'user_id' => $user->getAttribute('id'),
                'wid' => 0,
                'wallet_type' => $walletType,
                'money' => $money,
                'exchange_rate' => $exchangeRate,
                'remark' => '',
                'amount' => $amount,
                'applied_at' => Carbon::now(),
            ];
            $withdraw['status'] = Enum::WITHDRAW_STATUS_PENDING;

            /** @var UserWithdraw $withdrawModel */
            $withdrawModel = UserWithdraw::query()->create($withdraw);
            UserWalletService::outcome($withdrawModel, $amount, $walletType);
            DB::commit();

            return $withdrawModel;
        } catch (\Exception $exception) {
            Log::error($exception);
            DB::rollBack();
            throw $exception;
        }
    }

    public static function checkAccountBank($money = 0)
    {
        $bank = Setting::get('bank');
        if (($bank['balance'] - $money) < $bank['lowest_balance']) {
            throw new WithdrawException(sprintf('[%s]提现账户余额不足', $bank['account_id']));
        }

        $pendingAmount = UserWithdraw::query()->where(['status' => Enum::WITHDRAW_STATUS_PENDING])->sum('money');
        if ($bank['balance'] - ($pendingAmount + $money) < 0) {
            throw new WithdrawException(sprintf('[%s]提现账户余额不足', $bank['account_id']));
        }
    }

    public static function applyReturn(User $user, float $money = 0){

        if (($user->mode & UserMode::DISABLE_WITHDRAW) === UserMode::DISABLE_WITHDRAW) {
            throw new WithdrawException("提现暂不可用，请联系客服");
        }
        if ($user->getAttribute('status') != Enum::STATUS_ENABLED) {
            throw new WithdrawException("用户状态异常，请联系客服");
        }

        $count = ReturnMoneyLog::where('uid',$user->id)->where('status',3)->count();

        if ($count) {
            throw new WithdrawException('已有提现处理中');
        }

        $groupApply = GroupApply::where('user_id',$user->id)->first();

        $count = ReturnMoneyLog::where('uid',$user->id)->where('status',1)->count();

        if (!$count) {
            throw new WithdrawException('账户余额不足');
        }

        DB::beginTransaction();
        try {

            // 单位元
            $money = round($groupApply->amount * $count,2);
            $walletType = Enum::WALLET_TYPE_RETURN;

            $withdraw = [
                'user_id' => $user->getAttribute('id'),
                'wid' => 0,
                'wallet_type' => $walletType,
                'money' => $money,
                'exchange_rate' => 1,
                'remark' => '',
                'amount' => 0,
                'applied_at' => Carbon::now(),
            ];
            $withdraw['status'] = Enum::WITHDRAW_STATUS_PENDING;

            /** @var UserWithdraw $withdrawModel */
            $withdrawModel = UserWithdraw::query()->create($withdraw);
            ReturnMoneyLog::where('uid',$user->id)->where('status',1)->update(['status'=>3]);
            DB::commit();

            return $withdrawModel;
        } catch (\Exception $exception) {
            Log::error($exception);
            DB::rollBack();
            throw $exception;
        }
    }
}
